package org.act.BPEL2Automata.graphics;

import org.act.BPEL2Automata.automata.module.State;
import org.act.BPEL2Automata.graphics.model.Automaton;
import org.act.BPEL2Automata.graphics.model.State4G;
import org.act.BPEL2Automata.graphics.model.TransitionRule;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Display;

/**
 * This class used to draw Graph.
 * 
 * @author baoxiwu<bb@feijiao.info>,ACT,Beihang University
 * @version 0.9.0
 * @since 2010-05-17
 * 
 */
public class GraphPainterFactory {
	public static final Color HIGHLIGHT_COLOR = Display.getDefault().getSystemColor(SWT.COLOR_GREEN);
	public static final int CANVAS_SIZE_DEFAULT = 1000; 
	public static final int VERTEX_SPACE_SIZE_DEFAULT = 1000; 
	public static final int VERTEX_SPACING_DEFAULT = 25;
	public static final int VERTEX_BUFFER_SIZE_DEFAULT = 50;
	
	private GC gc = null;
	private Painter painter = null;
	
	public GraphPainterFactory(GC gc){
		this.gc = gc;
		this.painter = new Painter(this.gc);
	}
	
	
	public void draw(Automaton automaton){
		/*
		for(int i = 0; i < automaton.getStateSet().size(); i++){
			this.drawState(automaton.getStateSet().get(i));
		}
		
		for(int i = 0; i < automaton.getTransitionRuleSet().size(); i++){
			this.drawTransition(automaton.getTransitionRuleSet().get(i));
		}
		*/
		this.draw(automaton, null);
	}
	
	public void draw(Automaton automaton,State highlighted){
		for(int i = 0; i < automaton.getStateSet().size(); i++){
			if(automaton.getStateSet().get(i).getFrom() == highlighted){
				automaton.getStateSet().get(i).setColor(GraphPainterFactory.HIGHLIGHT_COLOR);
			}
			
			this.drawState(automaton.getStateSet().get(i));
		}
		
		for(int i = 0; i < automaton.getTransitionRuleSet().size(); i++){
			this.drawTransition(automaton.getTransitionRuleSet().get(i));
		}
	}
	
	private void drawState(State4G state){
		if(state.getType() == State4G.STATE4G_TYPE_OTHER){
			this.painter.drawCycle(state.getPoint().x, state.getPoint().y, state.getColor(), state.getID());
			
			if(state.getColor() == GraphPainterFactory.HIGHLIGHT_COLOR){
				state.resetColor();
			}
		}
		else
		if(state.getType() == State4G.STATE4G_TYPE_FINAL){
			this.painter.drawDualCycle(state.getPoint().x, state.getPoint().y, state.getColor(), state.getID());
			
			if(state.getColor() == GraphPainterFactory.HIGHLIGHT_COLOR){
				state.resetColor();
			}
		}
		else
		if(state.getType() == State4G.STATE4G_TYPE_START){
			//TODO need to add an ARROW to show that this is a start state?
			this.painter.drawCycle(state.getPoint().x, state.getPoint().y, state.getColor(), state.getID());
			
			if(state.getColor() == GraphPainterFactory.HIGHLIGHT_COLOR){
				state.resetColor();
			}
		}
	}
	
	private void drawTransition(TransitionRule tr){
		if(tr.getStartState() != tr.getEndState()){
			
			this.painter.drawArrow(tr.getStartState().getPoint().x, tr.getStartState().getPoint().y, 
					tr.getEndState().getPoint().x, tr.getEndState().getPoint().y, 
					"mes" + tr.getMessage().getID());
		}
		else{
			this.painter.drawArcWithArrow(tr.getStartState().getPoint().x, tr.getStartState().getPoint().y, 
					"mes" + tr.getMessage().getID());
		}
	}
}
